// cspell: ignore inbld
// cspell: ignore scal
// cspell: ignore ivmc
// cspell: ignore dbbp
// cspell: ignore texmc

import * as assert from "node:assert";
import { describe, it } from "node:test";

import { parseSequenceParameterSet } from "./h265.js";

describe("h265", () => {
    describe("h265ParseSequenceParameterSet", () => {
        it("complex data", () => {
            const buffer = new Uint8Array([
                0x01, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
                0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x99, 0xa0, 0x03, 0xc0,
                0x80, 0x11, 0x07, 0xf9, 0x65, 0x26, 0x49, 0x1b, 0x61, 0xa5,
                0x88, 0xaa, 0x93, 0x13, 0x0c, 0xbe, 0xcf, 0xaf, 0x37, 0xe5,
                0x9f, 0x5e, 0x14, 0x46, 0x27, 0x2e, 0xda, 0xc0, 0xff, 0xff,
                0x80,
            ]);

            const sps = parseSequenceParameterSet(buffer);

            assert.deepStrictEqual(sps, {
                sps_video_parameter_set_id: 0,
                sps_max_sub_layers_minus1: 0,
                sps_temporal_id_nesting_flag: true,
                profileTierLevel: {
                    generalProfileTier: {
                        profile_space: 0,
                        tier_flag: false,
                        profile_idc: 1,
                        profileCompatibilitySet: new Uint8Array([96, 0, 0, 0]),
                        profile_compatibility_flag: [
                            false,
                            true,
                            true,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                        ],
                        constraintSet: new Uint8Array([0, 0, 0, 0, 0, 0]),
                        progressive_source_flag: false,
                        interlaced_source_flag: false,
                        non_packed_constraint_flag: false,
                        frame_only_constraint_flag: false,
                        max_12bit_constraint_flag: undefined,
                        max_10bit_constraint_flag: undefined,
                        max_8bit_constraint_flag: undefined,
                        max_422chroma_constraint_flag: undefined,
                        max_420chroma_constraint_flag: undefined,
                        max_monochrome_constraint_flag: undefined,
                        intra_constraint_flag: undefined,
                        one_picture_only_constraint_flag: false,
                        lower_bit_rate_constraint_flag: undefined,
                        max_14bit_constraint_flag: undefined,
                        inbld_flag: false,
                    },
                    general_level_idc: 153,
                    sub_layer_profile_present_flag: [],
                    sub_layer_level_present_flag: [],
                    subLayerProfileTier: [],
                    sub_layer_level_idc: [],
                },
                sps_seq_parameter_set_id: 0,
                chroma_format_idc: 1,
                separate_colour_plane_flag: undefined,
                pic_width_in_luma_samples: 1920,
                pic_height_in_luma_samples: 1088,
                conformance_window_flag: true,
                conf_win_left_offset: 0,
                conf_win_right_offset: 0,
                conf_win_top_offset: 0,
                conf_win_bottom_offset: 0,
                bit_depth_luma_minus8: 0,
                bit_depth_chroma_minus8: 0,
                log2_max_pic_order_cnt_lsb_minus4: 4,
                sps_sub_layer_ordering_info_present_flag: true,
                sps_max_dec_pic_buffering_minus1: [4],
                sps_max_num_reorder_pics: [3],
                sps_max_latency_increase_plus1: [0],
                log2_min_luma_coding_block_size_minus3: 0,
                log2_diff_max_min_luma_coding_block_size: 3,
                log2_min_luma_transform_block_size_minus2: 0,
                log2_diff_max_min_luma_transform_block_size: 3,
                max_transform_hierarchy_depth_inter: 2,
                max_transform_hierarchy_depth_intra: 2,
                scaling_list_enabled_flag: false,
                sps_scaling_list_data_present_flag: undefined,
                scalingListData: undefined,
                amp_enabled_flag: true,
                sample_adaptive_offset_enabled_flag: true,
                pcm_enabled_flag: false,
                pcm_sample_bit_depth_luma_minus1: undefined,
                pcm_sample_bit_depth_chroma_minus1: undefined,
                log2_min_pcm_luma_coding_block_size_minus3: undefined,
                log2_diff_max_min_pcm_luma_coding_block_size: undefined,
                pcm_loop_filter_disabled_flag: undefined,
                num_short_term_ref_pic_sets: 12,
                shortTermRefPicSets: [
                    {
                        stRpsIdx: 0,
                        num_short_term_ref_pic_sets: 12,
                        inter_ref_pic_set_prediction_flag: false,
                        delta_idx_minus1: 0,
                        delta_rps_sign: false,
                        abs_delta_rps_minus1: 0,
                        used_by_curr_pic_flag: [],
                        use_delta_flag: [],
                        num_negative_pics: 4,
                        num_positive_pics: 0,
                        delta_poc_s0_minus1: [7, 1, 1, 3],
                        used_by_curr_pic_s0_flag: [true, true, true, true],
                        delta_poc_s1_minus1: [],
                        used_by_curr_pic_s1_flag: [],
                    },
                    {
                        stRpsIdx: 1,
                        num_short_term_ref_pic_sets: 12,
                        inter_ref_pic_set_prediction_flag: true,
                        delta_idx_minus1: 0,
                        delta_rps_sign: false,
                        abs_delta_rps_minus1: 3,
                        used_by_curr_pic_flag: [true, true, false, false, true],
                        use_delta_flag: [true, true, false, false, true],
                        num_negative_pics: 2,
                        num_positive_pics: 1,
                        delta_poc_s0_minus1: [5, 3],
                        used_by_curr_pic_s0_flag: [true, true],
                        delta_poc_s1_minus1: [3],
                        used_by_curr_pic_s1_flag: [true],
                    },
                    {
                        stRpsIdx: 2,
                        num_short_term_ref_pic_sets: 12,
                        inter_ref_pic_set_prediction_flag: true,
                        delta_idx_minus1: 0,
                        delta_rps_sign: false,
                        abs_delta_rps_minus1: 1,
                        used_by_curr_pic_flag: [true, true, true, true],
                        use_delta_flag: [true, true, true, true],
                        num_negative_pics: 2,
                        num_positive_pics: 2,
                        delta_poc_s0_minus1: [5, 5],
                        used_by_curr_pic_s0_flag: [true, true],
                        delta_poc_s1_minus1: [1, 3],
                        used_by_curr_pic_s1_flag: [true, true],
                    },
                    {
                        stRpsIdx: 3,
                        num_short_term_ref_pic_sets: 12,
                        inter_ref_pic_set_prediction_flag: true,
                        delta_idx_minus1: 0,
                        delta_rps_sign: false,
                        abs_delta_rps_minus1: 0,
                        used_by_curr_pic_flag: [true, false, true, true, true],
                        use_delta_flag: [true, false, true, true, true],
                        num_negative_pics: 1,
                        num_positive_pics: 3,
                        delta_poc_s0_minus1: [6],
                        used_by_curr_pic_s0_flag: [true],
                        delta_poc_s1_minus1: [0, 1, 3],
                        used_by_curr_pic_s1_flag: [true, true, true],
                    },
                    {
                        stRpsIdx: 4,
                        abs_delta_rps_minus1: 1,
                        delta_idx_minus1: 0,
                        delta_poc_s0_minus1: [2, 9],
                        delta_poc_s1_minus1: [0, 3],
                        delta_rps_sign: true,
                        inter_ref_pic_set_prediction_flag: true,
                        num_negative_pics: 2,
                        num_positive_pics: 2,
                        num_short_term_ref_pic_sets: 12,
                        use_delta_flag: [true, true, true, true, false],
                        used_by_curr_pic_flag: [true, true, true, true, false],
                        used_by_curr_pic_s0_flag: [true, true],
                        used_by_curr_pic_s1_flag: [true, true],
                    },
                    {
                        abs_delta_rps_minus1: 2,
                        delta_idx_minus1: 0,
                        delta_poc_s0_minus1: [3, 5, 11],
                        delta_poc_s1_minus1: [1],
                        delta_rps_sign: true,
                        inter_ref_pic_set_prediction_flag: true,
                        num_negative_pics: 3,
                        num_positive_pics: 1,
                        num_short_term_ref_pic_sets: 12,
                        stRpsIdx: 5,
                        use_delta_flag: [true, true, true, true, false],
                        used_by_curr_pic_flag: [true, true, true, true, false],
                        used_by_curr_pic_s0_flag: [true, true, true],
                        used_by_curr_pic_s1_flag: [true],
                    },
                    {
                        abs_delta_rps_minus1: 0,
                        delta_idx_minus1: 0,
                        delta_poc_s0_minus1: [4, 19],
                        delta_poc_s1_minus1: [0, 1],
                        delta_rps_sign: false,
                        inter_ref_pic_set_prediction_flag: true,
                        num_negative_pics: 2,
                        num_positive_pics: 2,
                        num_short_term_ref_pic_sets: 12,
                        stRpsIdx: 6,
                        use_delta_flag: [true, false, true, true, true],
                        used_by_curr_pic_flag: [true, false, true, true, true],
                        used_by_curr_pic_s0_flag: [true, true],
                        used_by_curr_pic_s1_flag: [true, true],
                    },
                    {
                        abs_delta_rps_minus1: 1,
                        delta_idx_minus1: 0,
                        delta_poc_s0_minus1: [2, 7, 21],
                        delta_poc_s1_minus1: [0],
                        delta_rps_sign: true,
                        inter_ref_pic_set_prediction_flag: true,
                        num_negative_pics: 3,
                        num_positive_pics: 1,
                        num_short_term_ref_pic_sets: 12,
                        stRpsIdx: 7,
                        use_delta_flag: [true, true, true, true, false],
                        used_by_curr_pic_flag: [true, true, true, true, false],
                        used_by_curr_pic_s0_flag: [true, true, true],
                        used_by_curr_pic_s1_flag: [true],
                    },
                    {
                        abs_delta_rps_minus1: 0,
                        delta_idx_minus1: 0,
                        delta_poc_s0_minus1: [7],
                        delta_poc_s1_minus1: [],
                        delta_rps_sign: false,
                        inter_ref_pic_set_prediction_flag: false,
                        num_negative_pics: 1,
                        num_positive_pics: 0,
                        num_short_term_ref_pic_sets: 12,
                        stRpsIdx: 8,
                        use_delta_flag: [],
                        used_by_curr_pic_flag: [],
                        used_by_curr_pic_s0_flag: [true],
                        used_by_curr_pic_s1_flag: [],
                    },
                    {
                        abs_delta_rps_minus1: 3,
                        delta_idx_minus1: 0,
                        delta_poc_s0_minus1: [5],
                        delta_poc_s1_minus1: [3],
                        delta_rps_sign: false,
                        inter_ref_pic_set_prediction_flag: true,
                        num_negative_pics: 1,
                        num_positive_pics: 1,
                        num_short_term_ref_pic_sets: 12,
                        stRpsIdx: 9,
                        use_delta_flag: [true, true],
                        used_by_curr_pic_flag: [true, true],
                        used_by_curr_pic_s0_flag: [true],
                        used_by_curr_pic_s1_flag: [true],
                    },
                    {
                        abs_delta_rps_minus1: 1,
                        delta_idx_minus1: 0,
                        delta_poc_s0_minus1: [5],
                        delta_poc_s1_minus1: [1, 3],
                        delta_rps_sign: false,
                        inter_ref_pic_set_prediction_flag: true,
                        num_negative_pics: 1,
                        num_positive_pics: 2,
                        num_short_term_ref_pic_sets: 12,
                        stRpsIdx: 10,
                        use_delta_flag: [true, true, true],
                        used_by_curr_pic_flag: [true, true, true],
                        used_by_curr_pic_s0_flag: [true],
                        used_by_curr_pic_s1_flag: [true, true],
                    },
                    {
                        abs_delta_rps_minus1: 0,
                        delta_idx_minus1: 0,
                        delta_poc_s0_minus1: [],
                        delta_poc_s1_minus1: [],
                        delta_rps_sign: false,
                        inter_ref_pic_set_prediction_flag: false,
                        num_negative_pics: 0,
                        num_positive_pics: 0,
                        num_short_term_ref_pic_sets: 12,
                        stRpsIdx: 11,
                        use_delta_flag: [],
                        used_by_curr_pic_flag: [],
                        used_by_curr_pic_s0_flag: [],
                        used_by_curr_pic_s1_flag: [],
                    },
                ],
                long_term_ref_pics_present_flag: false,
                num_long_term_ref_pics_sps: undefined,
                lt_ref_pic_poc_lsb_sps: undefined,
                used_by_curr_pic_lt_sps_flag: undefined,
                sps_temporal_mvp_enabled_flag: true,
                strong_intra_smoothing_enabled_flag: true,

                vui_parameters_present_flag: false,
                vuiParameters: undefined,

                sps_extension_present_flag: true,
                sps_range_extension_flag: false,
                sps_multilayer_extension_flag: true,
                sps_3d_extension_flag: true,
                sps_scc_extension_flag: false,
                spsMultilayerExtension: {
                    inter_view_mv_vert_constraint_flag: false,
                },
                sps3dExtension: {
                    iv_di_mc_enabled_flag: [true, true],
                    iv_mv_scal_enabled_flag: [true, true],
                    log2_ivmc_sub_pb_size_minus3: 0,
                    iv_res_pred_enabled_flag: true,
                    depth_ref_enabled_flag: true,
                    vsp_mc_enabled_flag: true,
                    dbbp_enabled_flag: true,
                    tex_mc_enabled_flag: true,
                    log2_texmc_sub_pb_size_minus3: 0,
                    intra_contour_enabled_flag: true,
                    intra_dc_only_wedge_enabled_flag: true,
                    cqt_cu_part_pred_enabled_flag: true,
                    inter_dc_only_enabled_flag: true,
                    skip_intra_enabled_flag: true,
                },
                sps_extension_4bits: 0,
                sps_extension_data_flag: undefined,
            } satisfies ReturnType<typeof parseSequenceParameterSet>);
        });

        it("issue #732", () => {
            const buffer = new Uint8Array([
                66, 1, 3, 1, 96, 0, 0, 3, 0, 0, 3, 0, 0, 3, 0, 0, 3, 0, 150, 0,
                0, 160, 2, 28, 128, 9, 33, 99, 107, 92, 146, 41, 187, 226, 170,
                151, 43, 182, 64,
            ]);

            const sps = parseSequenceParameterSet(buffer);

            assert.deepStrictEqual(sps, {
                sps_video_parameter_set_id: 4,
                sps_max_sub_layers_minus1: 1,
                sps_temporal_id_nesting_flag: false,
                profileTierLevel: {
                    generalProfileTier: {
                        profile_space: 0,
                        tier_flag: false,
                        profile_idc: 1,
                        profileCompatibilitySet: new Uint8Array([3, 1, 96, 0]),
                        profile_compatibility_flag: [
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            true,
                            true,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            true,
                            false,
                            true,
                            true,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                        ],
                        constraintSet: new Uint8Array([0, 0, 0, 0, 0, 0]),
                        progressive_source_flag: false,
                        interlaced_source_flag: false,
                        non_packed_constraint_flag: false,
                        frame_only_constraint_flag: false,
                        max_12bit_constraint_flag: false,
                        max_10bit_constraint_flag: false,
                        max_8bit_constraint_flag: false,
                        max_422chroma_constraint_flag: false,
                        max_420chroma_constraint_flag: false,
                        max_monochrome_constraint_flag: false,
                        intra_constraint_flag: false,
                        one_picture_only_constraint_flag: false,
                        lower_bit_rate_constraint_flag: false,
                        max_14bit_constraint_flag: undefined,
                        inbld_flag: false,
                    },
                    general_level_idc: 0,
                    sub_layer_profile_present_flag: [false],
                    sub_layer_level_present_flag: [false],
                    subLayerProfileTier: [],
                    sub_layer_level_idc: [],
                },
                sps_seq_parameter_set_id: 81923,
                chroma_format_idc: 6,
                separate_colour_plane_flag: undefined,
                pic_width_in_luma_samples: 3,
                pic_height_in_luma_samples: 583,
                conformance_window_flag: false,
                conf_win_left_offset: undefined,
                conf_win_right_offset: undefined,
                conf_win_top_offset: undefined,
                conf_win_bottom_offset: undefined,
                bit_depth_luma_minus8: 0,
                bit_depth_chroma_minus8: 2,
                log2_max_pic_order_cnt_lsb_minus4: 12,
                sps_sub_layer_ordering_info_present_flag: true,
                sps_max_dec_pic_buffering_minus1: [1, 1],
                sps_max_num_reorder_pics: [0, 0],
                sps_max_latency_increase_plus1: [0, 0],
                log2_min_luma_coding_block_size_minus3: 0,
                log2_diff_max_min_luma_coding_block_size: 3,
                log2_min_luma_transform_block_size_minus2: 0,
                log2_diff_max_min_luma_transform_block_size: 3,
                max_transform_hierarchy_depth_inter: 1,
                max_transform_hierarchy_depth_intra: 0,
                scaling_list_enabled_flag: false,
                sps_scaling_list_data_present_flag: undefined,
                scalingListData: undefined,
                amp_enabled_flag: false,
                sample_adaptive_offset_enabled_flag: true,
                pcm_enabled_flag: true,
                pcm_sample_bit_depth_luma_minus1: 7,
                pcm_sample_bit_depth_chroma_minus1: 7,
                log2_min_pcm_luma_coding_block_size_minus3: 0,
                log2_diff_max_min_pcm_luma_coding_block_size: 0,
                pcm_loop_filter_disabled_flag: false,
                num_short_term_ref_pic_sets: 4,
                shortTermRefPicSets: [
                    {
                        stRpsIdx: 0,
                        num_short_term_ref_pic_sets: 4,
                        inter_ref_pic_set_prediction_flag: false,
                        delta_idx_minus1: 0,
                        delta_rps_sign: false,
                        abs_delta_rps_minus1: 0,
                        used_by_curr_pic_flag: [],
                        use_delta_flag: [],
                        num_negative_pics: 1,
                        num_positive_pics: 0,
                        delta_poc_s0_minus1: [1],
                        used_by_curr_pic_s0_flag: [true],
                        delta_poc_s1_minus1: [],
                        used_by_curr_pic_s1_flag: [],
                    },
                    {
                        stRpsIdx: 1,
                        num_short_term_ref_pic_sets: 4,
                        inter_ref_pic_set_prediction_flag: false,
                        delta_idx_minus1: 0,
                        delta_rps_sign: false,
                        abs_delta_rps_minus1: 0,
                        used_by_curr_pic_flag: [],
                        use_delta_flag: [],
                        num_negative_pics: 1,
                        num_positive_pics: 0,
                        delta_poc_s0_minus1: [0],
                        used_by_curr_pic_s0_flag: [true],
                        delta_poc_s1_minus1: [],
                        used_by_curr_pic_s1_flag: [],
                    },
                    {
                        stRpsIdx: 2,
                        num_short_term_ref_pic_sets: 4,
                        inter_ref_pic_set_prediction_flag: false,
                        delta_idx_minus1: 0,
                        delta_rps_sign: false,
                        abs_delta_rps_minus1: 0,
                        used_by_curr_pic_flag: [],
                        use_delta_flag: [],
                        num_negative_pics: 1,
                        num_positive_pics: 0,
                        delta_poc_s0_minus1: [2],
                        used_by_curr_pic_s0_flag: [true],
                        delta_poc_s1_minus1: [],
                        used_by_curr_pic_s1_flag: [],
                    },
                    {
                        stRpsIdx: 3,
                        num_short_term_ref_pic_sets: 4,
                        inter_ref_pic_set_prediction_flag: false,
                        delta_idx_minus1: 0,
                        delta_rps_sign: false,
                        abs_delta_rps_minus1: 0,
                        used_by_curr_pic_flag: [],
                        use_delta_flag: [],
                        num_negative_pics: 0,
                        num_positive_pics: 0,
                        delta_poc_s0_minus1: [],
                        used_by_curr_pic_s0_flag: [],
                        delta_poc_s1_minus1: [],
                        used_by_curr_pic_s1_flag: [],
                    },
                ],
                long_term_ref_pics_present_flag: false,
                num_long_term_ref_pics_sps: undefined,
                lt_ref_pic_poc_lsb_sps: undefined,
                used_by_curr_pic_lt_sps_flag: undefined,
                sps_temporal_mvp_enabled_flag: true,
                strong_intra_smoothing_enabled_flag: true,
                vui_parameters_present_flag: false,
                vuiParameters: undefined,
                sps_extension_present_flag: false,
                sps_range_extension_flag: undefined,
                sps_multilayer_extension_flag: undefined,
                sps_3d_extension_flag: undefined,
                sps_scc_extension_flag: undefined,
                sps_extension_4bits: undefined,
                spsMultilayerExtension: undefined,
                sps3dExtension: undefined,
                sps_extension_data_flag: undefined,
            } satisfies ReturnType<typeof parseSequenceParameterSet>);
        });
    });
});
